//
//  SQL.m
//  SQL演练
//
//  Created by Guo Rui on 2017/10/27.
//  Copyright © 2017年 GR Harry. All rights reserved.
//

#import "SQLChain.h"

@interface SQLChain ()
@property (strong, nonatomic) NSMutableString *sql;

@end

@implementation SQLChain

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.sql = [NSMutableString string];
    }
    return self;
}





/************************************************** DDL ***************************************************/

- (SQLChainStringParamBlock)createTable
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *tableName){
        NSAssert(tableName != nil && tableName.length != 0, @"表名 不能为空");
        [self.sql appendFormat:@"CREATE TABLE IF NOT EXISTS %@", tableName];
        return weakself;
    };
}

- (SQLChainStringParamBlock)dropTable
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *tableName){
        NSAssert(tableName != nil && tableName.length != 0, @"表名 不能为空");
        [self.sql appendFormat:@"DROP TABLE IF EXISTS %@", tableName];
        return weakself;
    };
}

- (SQLChainDoubleStringParamBlock)renameTable
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *oldTableName, NSString *newTableName){
        NSAssert(oldTableName != nil && oldTableName.length != 0, @"旧表名 不能为空");
        NSAssert(newTableName != nil && newTableName.length != 0, @"旧表名 不能为空");
        [weakself.sql appendFormat:@"ALTER TABLE %@ RENAME TO %@", oldTableName, newTableName];
        return weakself;
    };
}

- (SQLChainDoubleStringParamBlock)addcolumn
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *tableName, NSString *field){
        NSAssert(tableName != nil && tableName.length != 0, @"表名 不能为空");
        [weakself.sql appendFormat:@"ALTER TABLE %@ ADD COLUMN %@", tableName, field];
        return weakself;
    };
}

/************************************************** DML ***************************************************/
- (SQLChainStringParamBlock)insert
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *tableName){
        NSAssert(tableName != nil && tableName.length != 0, @"表名 不能为空");
        [self.sql appendFormat:@"INSERT INTO %@", tableName];
        return weakself;
    };
}

- (SQLChainInsertParamBlock)insert_into
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain * (NSString *tableName, NSArray *fields, NSArray *values){
        return weakself.insert(tableName).fields(fields).values(values);
    };
}

- (SQLChainStringParamBlock)update
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *tableName){
        NSAssert(tableName != nil && tableName.length != 0, @"表名 不能为空");
        
        [self.sql appendFormat:@"UPDATE %@", tableName];
        return weakself;
    };
}

- (SQLChainUpdateParamBlock)update_set
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *tableName, NSArray *fields, NSArray *values){
        return weakself.update(tableName).set(fields, values);
    };
}

- (SQLChainStringParamBlock)del
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *tableName){
        NSAssert(tableName != nil && tableName.length != 0, @"表名 不能为空");
        
        [self.sql appendFormat:@"DELETE FROM %@", tableName];
        return weakself;
    };
}

/************************************************** DQL ***************************************************/
- (SQLChainArrayParamBlock)select
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSArray *fields) {
        NSAssert(fields != nil && fields.count != 0, @"用于查询的字段名数组 不能为空");
        
        [weakself.sql appendString:@"SELECT "];
        
        NSInteger fieldCount = fields.count;
        [fields enumerateObjectsUsingBlock:^(NSString * _Nonnull field, NSUInteger idx, BOOL * _Nonnull stop) {
            [weakself.sql appendString:field];
            if (idx != fieldCount - 1) {
                [weakself.sql appendString:@","];
            }
        }];
        
        return weakself;
    };
}

- (SQLChainNoParamBlock)selectAll
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain * {
        [weakself.sql appendString:@"SELECT * "];
        return weakself;
    };
}

/************************************************** 条件语句 ***************************************************/

- (SQLChainStringParamBlock)where
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *condition){
        NSAssert(condition != nil && condition.length != 0, @"条件语句 不能为空");
        
        [self.sql appendFormat:@" WHERE %@", condition];
        return weakself;
    };
}

/************************************************** 排序语句 ***************************************************/

- (SQLChainStringParamBlock)orderby
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *orderStr){
        NSAssert(orderStr != nil && orderStr.length != 0, @"排序语句 不能为空");
        
        [self.sql appendFormat:@" ORDER BY %@", orderStr];
        return weakself;
    };
}

/************************************************** 分页语句 ***************************************************/

- (SQLChainDoubleIntParamBlock)limit
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSInteger start, NSInteger length){
        [self.sql appendFormat:@" LIMIT %zd, %zd", start, length];
        return weakself;
    };
}

/************************************************** 连接符 ***************************************************/

- (SQLChainStringParamBlock)fieldsDefine
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *fieldsDefineStr){
        NSAssert(fieldsDefineStr != nil && fieldsDefineStr.length != 0, @"字段声明语句 不能为空");
        
        [self.sql appendFormat:@" (%@)", fieldsDefineStr];
        return weakself;
    };
}

- (SQLChainArrayParamBlock)fields
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSArray *fieldNames){
        NSAssert(fieldNames != nil && fieldNames.count != 0, @"字段名数组 不能为空");
        
        [weakself.sql appendString:@" ("];
        
        NSInteger fieldCount = fieldNames.count;
        [fieldNames enumerateObjectsUsingBlock:^(NSString * _Nonnull fieldName, NSUInteger idx, BOOL * _Nonnull stop) {
            if (idx != fieldCount - 1) {
                [weakself.sql appendFormat:@"%@,", fieldName];
            }
            else {
                [weakself.sql appendFormat:@"%@)", fieldName];
            }
        }];
        return weakself;
    };
}

- (SQLChainArrayParamBlock)values
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSArray *values){
        NSAssert(values != nil && values.count != 0, @"值数组 不能为空");
        
        [weakself.sql appendString:@" VALUES ("];
        
//        NSInteger valueCount = values.count;
        //        [values enumerateObjectsUsingBlock:^(id  _Nonnull value, NSUInteger idx, BOOL * _Nonnull stop) {
        //            NSString *formatStr = @"%@";
        //            if ([value isKindOfClass:[NSString class]]) {
        //                if (![value isEqualToString:@"?"]) {
        //                    formatStr = @"'%@'";
        //                }
        //            }
        //
        //            if (idx == valueCount - 1) {
        //                formatStr = [formatStr stringByAppendingString:@")"];
        //            }
        //            else {
        //                formatStr = [formatStr stringByAppendingString:@","];
        //            }
        //            [weakself.sql appendFormat:formatStr, value];
        //        }];
        
        for (id value in values) {
            NSString *formatStr = @"%@,";
            if ([value isKindOfClass:[NSString class]]) {
                if (![value isEqualToString:@"?"]) {
                    formatStr = @"'%@',";
                }
            }
            [weakself.sql appendFormat:formatStr, value];
        }
        [weakself.sql replaceCharactersInRange:NSMakeRange(weakself.sql.length - 1, 1) withString:@")"];
        return weakself;
    };
}

- (SQLChainDoubleArrayParamBlock)set
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSArray *fields, NSArray *values) {
        NSAssert(fields != nil && fields.count != 0, @"用于更新的字段名数组 不能为空");
        NSAssert(values != nil && values.count != 0, @"用于更新的值数组 不能为空");
        NSAssert(values.count == fields.count, @"用于更新的字段名数组和值数组元素个数必须一致");
        
        [weakself.sql appendString:@" SET "];
        
        NSInteger fieldCount = fields.count;
        [fields enumerateObjectsUsingBlock:^(NSString * _Nonnull fieldName, NSUInteger idx, BOOL * _Nonnull stop) {
            id value = [values objectAtIndex:idx];
            NSString *formatStr = @"%@ = %@";
            if ([value isKindOfClass:[NSString class]] && ![value isEqualToString:@"?"]) {
                formatStr = @"%@ = '%@'";
            }
            [weakself.sql appendFormat:formatStr, fieldName, value];
            if (idx != fieldCount - 1) {
                [weakself.sql appendString:@","];
            }
        }];
        
        return weakself;
    };
}

- (SQLChainStringParamBlock)from
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* (NSString *tableName) {
        NSAssert(tableName != nil && tableName.length != 0, @"表名 不能为空");
        
        [weakself.sql appendFormat:@" FROM %@", tableName];
        return weakself;
    };
}


- (SQLChainNoParamBlock)end
{
    __weak typeof(self) weakself = self;
    return ^ SQLChain* {
        [weakself.sql appendString:@";"];
        return weakself;
    };
}

/************************************************** Debug ***************************************************/

- (SQLChainNoParamBlock)output
{
    return ^ SQLChain* {
        SQLLog(@"%@", self.sql);
        return self;
    };
}

- (NSString *)sqlString
{
    return self.sql.copy;
}

- (void)reset
{
    self.sql = [NSMutableString stringWithCapacity:0];
}

@end
